package com.mall.user.services;

import com.alibaba.fastjson.JSON;
import com.mall.commons.tool.exception.ValidateException;
import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.converter.UserConverterMapper;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dto.CheckAuthRequest;
import com.mall.user.dto.CheckAuthResponse;
import com.mall.user.dto.UserLoginRequest;
import com.mall.user.dto.UserLoginResponse;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class LoginServiceImpl implements ILoginService {

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserConverterMapper converterMapper;

    @Override
    public UserLoginResponse login(UserLoginRequest request) {
        // 请求参数校验
        request.requestCheck();

        // 验证用户是否已经激活
        String p = request.getPassword();
        String pwd = DigestUtils.md5DigestAsHex(p.getBytes());
        Example example = new Example(Member.class);
        example.createCriteria()
                .andEqualTo("username", request.getUserName())
                .andEqualTo("password", pwd);

        UserLoginResponse loginResponse;
        List<Member> members = memberMapper.selectByExample(example);
        loginResponse = new UserLoginResponse();
        if (CollectionUtils.isEmpty(members)) {
            loginResponse.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
            loginResponse.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
            return loginResponse;
        }

        // 注册用户信息，验证是否激活
        Member member = members.get(0);
        String isVerified = member.getIsVerified();
        if ("N".equals(isVerified)) {
            loginResponse.setCode(SysRetCodeConstants.USER_ISVERFIED_ERROR.getCode());
            loginResponse.setMsg(SysRetCodeConstants.USER_ISVERFIED_ERROR.getMessage());
            return loginResponse;
        }

        // 登录成功，为登录成功的用户生成token
        loginResponse = converterMapper.converter(member);

        // 利用将用来生成token的 uid，file，username等信息放入map中
        HashMap<String, Object> map = new HashMap<>();
        map.put("uid", member.getId());
        //# issue 2 数据库中，file(头像图片)的值为null会导致前端出现空指针
        //map.put("file", member.getFile());
        map.put("username", member.getUsername());


        String token = JwtTokenUtils.builder()
                // 这里和toJSON.toString 有区别?
                .msg(JSON.toJSONString(map))
                .build()
                .creatJwtToken();

        loginResponse.setToken(token);
        loginResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        loginResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        return loginResponse;
    }

    @Override
    public UserLoginResponse logout(UserLoginRequest request) {
        return null;
    }

    @Override
    public CheckAuthResponse validToken(CheckAuthRequest request) {
        request.requestCheck();

        String token = request.getToken();
        String userInfo;
        try {
            userInfo = JwtTokenUtils.builder().token(token).build().freeJwt();
            log.info("validToken" + userInfo);
        } catch (ValidateException e) {
            // 解析 jwt失败
            CheckAuthResponse checkAuthResponse = new CheckAuthResponse();
            checkAuthResponse.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
            checkAuthResponse.setMsg(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
            return checkAuthResponse;
        }


        // 验证成功，返回response
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();
        checkAuthResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        checkAuthResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        checkAuthResponse.setUserinfo(userInfo);

        return checkAuthResponse;
    }
}
